package org.app.format;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.sound.sampled.Port;

import org.app.PortStatus;
import org.app.Ports;
import org.app.data.MyBean;
import org.app.label.WeHistory;

public class WeSerialize {

	WeHistory history=new WeHistory();
	PortStatus status;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		String result="";
		Object bean=new Object[]{"1",2,3.0,false};
		
		WeSerialize format=new WeSerialize();
		result=format.encrypt(bean).toString();
		System.out.println(result);
	}
	
	 private <T> Map toMap(final T t) {
			final Map map = new HashMap();
			// System.out.println(t);
			MyBean.visit(t, new Ports() {

				@Override
				public Object execute(Object obj) {
					// TODO Auto-generated method stub
					PropertyDescriptor pd = (PropertyDescriptor) obj;
					Class type = pd.getPropertyType();
					String name = pd.getName();
//					if (name.equals("class"))
//						return null;
					try {
						map.put(pd.getName(), pd.getReadMethod().invoke(t));
					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalArgumentException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					return null;
				}
			});
			return map;
		}
	
	/**
	 * 加密 对象转string
	 * @param t
	 * @return
	 */
	public <T> StringBuffer encrypt(T t) {
		StringBuffer sb = new StringBuffer();
		if (t == null)
			return sb;
		if (t instanceof Number) {
			sb.append(status.changeTo("NUMBER").execute(t));
		} else if (t instanceof String) {
			sb.append(status.changeTo("STRING").execute(t));
		} else if (t.getClass().getClassLoader() != null) {// 用户自定义类型
			Map map = this.toMap(t);
			sb.append(byMap(map));
		} else if (t instanceof Map) {
			
			sb.append(byMap((Map)t));
		} else 
			
			//关于数组，长度+1,下标[0]保存其类型 List/Vector/Object[] 等
		if (t instanceof List) {
			List list = (List) t;
			int size = list.size();
			if (size <= 0)
				return sb;

			Object[] format = new Object[size+1];
			 format[size]=t.getClass();
			for (int i = 0; i < size; i++) {
				format[i] = encrypt(list.get(i)).toString();
			}
           
            sb.append(byArray(format));
		}else 
		if (t.getClass().isArray()) {
			int size = Array.getLength(t);
			if (size <= 0)
				return sb;
			Object[] format = new Object[size+1];
			format[size]=t.getClass(); /////////bug 修改了数组顺序
			for (int i = 0; i < size; i++) {
				format[i] = encrypt(Array.get(t, i)).toString();
			}

			// sb.setCharAt(sb.length()-1, parallelRight);
			sb.append(byArray(format));
		}else{
			sb.append(t);
		}
		return sb;
	}
	
	
	

	
	public StringBuffer byMap(Map map){
		StringBuffer sb=new StringBuffer();
		Set<Entry> set = map.entrySet();
		Object[] format=new Object[map.size()];
		int id=0;
		
		for (Entry<String,Object> entry : set) {
			Object value = entry.getValue();
			String key=entry.getKey();
			if (value== null||"".equals(value)) {
				continue;
			}
			
			if(key.equals("class")){//
				format[format.length-1]=value;
			}else{
		
			format [id]=status.changeTo("MAP").execute(key,encrypt(value));
			id++;
			}
			
		}
		sb.append(byMap(format));
		return sb;
	}
	
	public String byMap(Object[] values) {
		// TODO Auto-generated method stub
		
		int size=values.length;
		if(values[size-1] instanceof Class){//区分map为自定义类？map类型
			size--;
		}
		for(int i=size-1;i>=0;i--){
			if(values[i]==null||values[i].equals("")){
				size--;
			}else{
				break;
			}
		}	
		String format=String.format(getParallel(size), values);
		return String.format(EnumJSON.MAPS.value, format);
	}

	
	

	/**
	 * 数组不应有空值
	 */
	public String byArray(Object[] values) {
		// TODO Auto-generated method stub
		String format=getParallel(values.length-1);
		//values[0]=values[values.length-1];// 类型不需格式化
		format=String.format(format, values);
		return String.format(status.changeTo("ARRAY").execute( format));
	}

	private String getParallel(int size){
		StringBuffer sb=new StringBuffer();
		for(int i=0;i<size;i++){
			sb.append("%s,");
		}
		return sb.substring(0,sb.length()-1);
	}
}
